package com.alinesno.cloud.common.web.base.form;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alinesno.cloud.common.core.orm.id.SnowflakeIdWorker;

/**
 * 表单提交拦截器
 * 
 * @author LuoAnDong
 * @since 2019年2月8日 上午10:43:38
 */
 @Aspect
 @Component
public class FormTokenAop {

	private static final Logger log = LoggerFactory.getLogger(FormTokenAop.class);
	private static final String FORM_TOKEN = "formToken";

	/**
	 * 创建token
	 * 
	 * @param joinPoint
	 * @param token
	 */
	@SuppressWarnings("unused")
	@Before("@annotation(token)")
	public void buildToken(final JoinPoint joinPoint, FormToken token) {
		log.debug("token = {}", token);
		try {
			if (token != null) {

				// 获取 joinPoint 的全部参数
				Object[] args = joinPoint.getArgs();
				HttpServletRequest request = null;
				HttpServletResponse response = null;

				for (int i = 0; i < args.length; i++) {
					// 获得参数中的 request && response
					if (args[i] instanceof HttpServletRequest) {
						request = (HttpServletRequest) args[i];
					}
					if (args[i] instanceof HttpServletResponse) {
						response = (HttpServletResponse) args[i];
					}
				}

				boolean needSaveSession = token.save();
				if (needSaveSession) {
					String uuid = SnowflakeIdWorker.getIdStr();
					log.debug("request = {}", request);
					request.getSession().setAttribute(FORM_TOKEN, uuid);
					log.debug("进入表单页面，Token值为：" + uuid);
				}

				boolean needRemoveSession = token.remove();
				if (needRemoveSession) {
					if (isRepeatSubmit(request)) {
						log.error("表单重复提交");
						throw new FormRepeatException("表单重复提交");
					}
					request.getSession(false).removeAttribute(FORM_TOKEN);
				}
			}

		} catch (FormRepeatException e) {
			throw e;
		} catch (Exception e) {
			e.printStackTrace();
			log.error("FORM_TOKEN 发生异常 : " + e);
		}
	}

	/**
	 * 判断是否重复提交
	 * 
	 * @param request
	 * @return
	 * @throws FormRepeatException
	 */
	private boolean isRepeatSubmit(HttpServletRequest request) throws FormRepeatException {
		Object serverTokenObj = request.getSession(false).getAttribute(FORM_TOKEN);

		if (serverTokenObj == null) {
			return true;
		}

		String clinetToken = request.getParameter(FORM_TOKEN);
		if (clinetToken == null || clinetToken.equals("")) {
			return true;
		}

		if (!serverTokenObj.equals(clinetToken)) {
			return true;
		}

		log.debug("校验是否重复提交：表单页面 FORM_TOKEN 值为：" + clinetToken + ",Session中的 FORM_TOKEN 值为:" + serverTokenObj);
		return false;
	}
	
}
